﻿// Original author contact info: Owen Emlen (owene_1998@yahoo.com)
// Note: other individuals may also have contributed to this code
// Project hosted on CodePlex.com as of 1/10/2009 at http://wpfimageviewer.codeplex.com
using System;
using System.IO;
using System.Linq;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Text;
using BrainTechLLC;
using BrainTechLLC.WPF;
using System.Windows.Data;
using System.Diagnostics;
using System.Windows.Controls;
using System.Windows.Threading;
using System.Windows;
using System.Collections.Specialized;
using DirectoryViewModels;
using System.Threading;
using BrainTechLLC.ThreadSafeObjects;

namespace BrainTechLLC.FolderExplorer
{
    public partial class FolderViewModel : BaseNotifyPropertyChangedUI
    {        
        public FolderViewModel FindInImmediateChildren(Func<FolderViewModel, bool> func, Func<FolderViewModel, bool> lookInDir, ref Dictionary<string, FolderViewModel> nextLevel)
        {
            if (nextLevel == null)
                nextLevel = new Dictionary<string, FolderViewModel>();

            var all = GetSubFoldersImmediate();
            for (int n = 0; n < all.Count; n++)
            {
                var sf = all[n];

                if (!lookInDir(sf))
                    continue;

                if (!nextLevel.ContainsKey(sf.FullPath))
                {
                    nextLevel.Add(sf.FullPath, sf);
                }
            }

            for (int n = 0; n < all.Count; n++)
            {
                var subfold = all[n];

                if (func(subfold))
                    return subfold;
            }

            return null;
        }

        public void RecurseParents(Action<FolderViewModel> action, bool performOnThis)
        {
            if (performOnThis)
            {
                action(this);
            }

            if (_parent != null)
            {
                _parent.RecurseParents(action, true);
            }
        }
     
        public void CrawlParentTree(Action<FolderViewModel> action)
        {
            action(this);
            if (this.Parent != null)
            {
                this.Parent.CrawlParentTree(action);
            }
        }

        public bool CrawlParentTreeAnyTrue(Predicate<FolderViewModel> action)
        {
            if (action(this))
                return true;

            if (this.Parent != null)
            {
                return this.Parent.CrawlParentTreeAnyTrue(action);
            }

            return false;
        }

        public void DoRecursive(Action<FolderViewModel> action)
        {
            action(this);
            
            var all = GetSubFoldersImmediate();
            for (int n = 0; n < all.Count; n++)
            {
                var sub = all[n];
                sub.DoRecursive(action);
            }
        }

        protected void CrawlInMemoryFolders(Action<FolderViewModel> action, List<FolderViewModel> folders)
        {
            if (this.SubFoldersCached != null)
            {
                int subFoldersCount = this.SubFoldersCached.Count;
                for (int n = 0; n < subFoldersCount; n++)
                {
                    var folder = this.SubFoldersCached[n];
                    if (action != null)
                    {
                        action(folder);
                    }
                    folders.Add(folder);
                    folder.CrawlInMemoryFolders(action, folders);
                }
            }
        }

        protected void CrawlInMemoryFolders(Action<FolderViewModel> action)
        {
            if (this.SubFoldersCached != null)
            {
                int subFoldersCount = this.SubFoldersCached.Count;
                for (int n = 0; n < subFoldersCount; n++)
                {
                    var folder = this.SubFoldersCached[n];
                    if (action != null)
                    {
                        action(folder);
                    }
                    folder.CrawlInMemoryFolders(action);
                }
            }
        }

        public ObservableCollection<FolderViewModel> FindSiblings()
        {
            if (this.Parent == null)
            {
                return new ObservableCollection<FolderViewModel>();
            }
            return this.Parent.SubFolders;
        }

        public FolderViewModel FindRoot()
        {
            if (this.Parent == null)
            {
                return this;
            }
            return this.Parent.FindRoot();
        }
    }
}
